package com.gw.smscheck.security.sys;

import com.gw.smscheck.entity.sys.Log;
import com.gw.smscheck.entity.sys.LogMapping;
import com.gw.smscheck.entity.sys.User;
import com.gw.smscheck.service.sys.LogMappingService;
import com.gw.smscheck.service.sys.LogService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 自定义过滤器
 * @author: JunYaoWang
 * @create: 2018-08-17 15:04
 */
public class LogFilter implements Filter {

    @Autowired
    private LogService logService;

    @Autowired
    private LogMappingService logMappingService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest)request;
////        HttpServletResponseWrapper httpResponse = new HttpServletResponseWrapper((HttpServletResponse) response);
////        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String servletPath = httpRequest.getServletPath();
//        // 获取请求参数
        String context = "";
        Map<String, String[]> map = httpRequest.getParameterMap();
        if(map.size() != 0){
            for (Map.Entry<String, String[]> entry : map.entrySet()) {
                context += entry.getKey() + "：" + ArrayUtils.toString(entry.getValue()) ;
            }
        }
        Integer userId = (Integer) httpRequest.getSession().getAttribute("userId");// 获取登录用户id
        String loginName = (String) httpRequest.getSession().getAttribute("userName");// 获取登录用户名

        //1.查询log_mapping表内是否存在该请求路径
//        System.out.println("请求路径："+servletPath);
        LogMapping logMapping = new LogMapping();
        logMapping.setUrl(servletPath);
        List<LogMapping> logMappingList = logMappingService.findByUrl(logMapping);
        if(logMappingList.size() > 0){
            //2.若存在，将该次请求操作存入log表
            Log log = new Log();
            if("/loginController/loginCheck".equals(servletPath)){// 如果是登陆 将登陆时请求的登陆名存入
                String[] requestUserName = map.get("loginName");
                log.setRequestUserName(requestUserName[0]);// 请求人名
            }else {
                log.setRequestUserName(loginName);
                log.setDescription(context);// 请求参数
            }
            if(userId != null){
                log.setRequestUser(userId);//请求人
            }
            log.setRequestIp(getIpAddr(httpRequest));// 请求ip
            log.setUrl(logMappingList.get(0).getUrl());// url
            log.setSensitiveType(logMappingList.get(0).getSensitiveType());// 敏感等级
            log.setRequestType(logMappingList.get(0).getDescription());// 请求类型
            logService.add(log);
//            String ip = getIpAddr(httpRequest);
        }
        filterChain.doFilter(request, response);//不需要过滤
    }

    @Override
    public void destroy() {

    }


    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
     *
     * @param request
     * @return
     * @throws IOException
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
    }
}
